package com.example.demo.jdk.reflect;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * 通过反射了解集合泛型的本质
 * 编译之后集合的泛型是去泛型化的
 *
 * @author: htc
 * @date: Created in 11:24 2018/12/17.
 */
public class Demo2 {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        Class arrayListClass = arrayList.getClass();

        List<String> list = new ArrayList<>();
        list.add("asvdvf");
        Class listClass = list.getClass();

        System.out.println(arrayListClass == listClass);

        System.out.println("######################################");

        ArrayList<String> sa = new ArrayList<String>();
        sa.add("asdfb");
        Class saClass = sa.getClass();
        System.out.println(saClass == listClass);


        System.out.println("######################################");

        /**
         * arrayListClass=listClass  salClass=listClass说明编译之后集合的泛型是去泛型化的
         * Java中集合的泛型，是防止错误输入的，只在编译阶段有效,绕过编译就无效了
         * 通过方法的反射可以绕过编译
         */
        //反射的操作都是编译之后的操作
        Class c = list.getClass();
        try {
            //通过反射绕过编译的类型检查
            list.getClass().getMethod("add",Object.class).invoke(list, 5);
            System.out.println(list);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        test();
    }

    static void test() {
        System.out.println("################################");

        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);

        Class listClazz = list.getClass();
        try {
           listClazz.getMethod("add", Object.class).invoke(list, "bbbb");
            System.out.println(list);

            System.out.println(list.get(0).getClass());
            System.out.println(list.get(3).getClass());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
